#ifndef MPEGTS_H
#define MPEGTS_H
#include <libmsprotocol/msprotocol.h>
#include "mpeg/mssi.h"
#include "mpeg/program.h"

#define	mode_unkonw			0
#define	mode_bctPcr			(1<<0)	//001，通过PCR进行码率控制
#define	mode_bctPtsDts		(1<<1)	//002，通过PTS/DTS进行码率控制
#define	mode_monitor		(1<<2)	//004，流监测，包括同步丢失、同步字节错误、PAT错误、连续计数错误、PMT错误、关键PID丢失、传输错误、CRC错误、PCR间隔错误、流信息改变和SDT错误
#define	mode_parseInfo		(1<<3)	//008，信息解析。一旦获取完成后，为了避免消耗，后续不再继续解析
#define	mode_parsePes		(1<<4)	//016，PES信息解析
#define	mode_pidStatistics	(1<<5)	//032，PID统计分析
#define	mode_filterNullPkt	(1<<6)	//064，空包过滤
#define	mode_rebuildPatPmt	(1<<7)	//128，重新生成PAT和PMT表

/*两个PCR之前的差值-系统消耗时间>BTC_PST_UNVALID，则认为PCR发生了翻转，单位us*/
#define BTC_PST_UNVALID 	ms_usseconds(2)
/*代码消耗的时间，单位us*/
#define BTC_PST_SYSUSE		ms_useconds(100) 
typedef struct RATEEMUContxt{	
	ms_s64 timeStream_pre;
	ms_s64 timeSys_pre;
	ms_u08 num_failed;
}RATEEMUContxt;

typedef struct MAPContxt{
	ms_u16 program_num_org;
	ms_u16 program_num;
	ms_u16 pmt_pid;
	ms_u16 pcr_pid;
	ms_u16 es_num;
	ms_u16 es_pid_org[MAX_ES];
	ms_u16 es_pid[MAX_ES];
	ms_byte service_name[256];
	ms_byte service_provider_name[256];	
	ms_bool flag_map_program_num;
	ms_bool flag_map_pmt_pid;
	ms_bool flag_map_pcr_pid;
	ms_bool flag_map_pcrPid_same_esPid;
	ms_bool flag_map_name;
	ms_bool flag_map_es[MAX_ES];


	ms_s16 pcr_es_index;	//PCR和ES的PID相同
	ms_u08 pcr_cc;
	ms_u08 es_cc[MAX_ES];
}MAPContxt;

typedef struct MAPLISTContxt{
	ms_s32 num_map;
	MAPContxt map_ctt[MAX_PROGRAM];
}MAPLISTContxt;
typedef struct SDTPARAMContxt{
	ms_u32 totalnum;
	ms_u16 serviceidList[MAX_PROGRAM];
	ms_u16 service_type[MAX_PROGRAM];
	ms_byte spnList[MAX_PROGRAM][64];
	ms_byte snList[MAX_PROGRAM][64];
}SDTPARAMContxt;
typedef struct PATPARAMContxt{
	ms_u32 totalnum;
	ms_u16 serviceidList[MAX_PROGRAM];//节目号
	ms_u16 pmtIdList[MAX_PROGRAM];
}PATPARAMContxt;
typedef struct PMTPARAMContxt{
	ms_u16 program_num;
	ms_u16 pid;
	ms_u16 pcr_pid;
	ms_s08 num_es;
	ESInfo EsInfo[MAX_ES];
	ms_u08 cc;
}PMTPARAMContxt;

#ifndef MPEGTS_C
extern ms_void 
	mpegts_api_getPidErr(void *stream_info_p);
extern ms_void 
	mpegts_api_getPidInfo(PIDLISTContxt *pidList_ctt,PIDContxt *pbr_ctt,void *stream_info_p);
extern ms_s64 
	mpegts_api_rateEmuLong(char * tag,char * exStr,RATEEMUContxt * sbrt,ms_s64 timeStream_cur,ms_bool flag_dbg);
extern ms_bool 
	mpegts_api_getStreamInfo(STREAMInfo stream_info,char *outbuf,ms_bool flag_format);
extern ms_s32 
	mpegts_api_buildPat( ms_byte * pTsPkt,ms_u08 *cc,ms_u08 pktSize,ms_byte adaption_field_control,
		ms_u16 transport_stream_id,PATPARAMContxt *pat_ctt);
extern ms_void 
	mpegts_api_parsePat( ms_byte * bufPat,ms_s32 len);
extern ms_s32 
	mpegts_api_buildPmt( ms_byte *ptspkt,ms_u08 *cc,ms_u08 pktSize,ms_byte adaption_field_control,
		ms_u16 program_num,ms_u16 pid,ms_u16 pcr_pid,ms_s08 num_es, ESInfo *pEsInfoArry);
extern ms_void 
	mpegts_api_parsePmt(ms_byte * buf, ms_u16 pmt_pid, ms_s32 len);
extern void 
	mpegts_api_buildsdt2( ms_byte *ptspkt,ms_u08 cc,ms_u08 pktSize,ms_byte adaption_field_control,ms_u16 service_id,
		ms_string service_provider_name,ms_string service_name,ms_u16 transport_stream_id,ms_u16 original_network_id);
extern ms_bool 
	mpegts_api_isEsPid(ms_u16 pid,ms_s08 num_es, ESInfo *pEsInfoArry);
extern ms_s32 
	mpegts_api_getTsPos(ms_string inurl);
extern ms_s32 
	mpegts_api_getTsPos2(ms_byte *buf,ms_s32 len);
extern ms_u08 
	mpegts_api_getTsPktSize(ms_string inurl,ms_string interfaceIn,char *format,ms_bool flag_vod);
extern ms_u08 
	mpegts_api_getTsPktSize2(ms_string inurl,ms_string interfaceIn,char *format,ms_bool flag_vod);
extern ms_u08 
	mpegts_api_getTsPktSize3(ms_byte *databuf,ms_s32 len);
extern ms_bool 
	mpegts_api_isFileNMpegts(ENUPROTOCOLIndex ptcIndex,ms_string purl,ms_string format);
extern ms_bool 
	mpegts_api_isMpeg(ms_string format,ms_u16 pid);
extern ms_bool 
	mpegts_api_isMpeg2(ms_string format);
extern ms_void 
	mpegts_api_parseSdt(ms_byte * bufSdt, ms_s32 len);
extern ms_void 
	mpegts_api_buildNullPkt( ms_byte * ptspkt,ms_u08 pktSize);
extern void 
	mpegts_api_rtpDemux(ms_u32 logopt,ms_string inurl, ms_string outurl,ms_s32 len_perrtppkg,ms_bool flag_rtpovertcp);
extern void 
	mpegts_api_tsExtract(ms_u32 logopt,ms_string inurl, ms_string outurl);
extern void 
	mpegts_api_tsMonitor(ms_u32 logopt,ms_string inurl,ms_string interfaceIn,
		ms_bool dbgAv,ms_bool dbgEs,ms_bool flag_vod);
extern void 
	mpegts_api_tsApiTest(ms_u32 logopt,ms_string target);
extern ms_void 
	mpegts_api_init(ms_void);
extern ms_string 
	mpegts_api_getStreamType(ms_u08 stream_type);
extern ms_string 
	mpegts_api_getServiceType(ms_u16 service_type);
extern ms_string 
	mpegts_api_getAVType(ms_u08 avType);
#else
ms_void 
	mpegts_api_getPidErr(void *stream_info_p);
ms_void 
	mpegts_api_getPidInfo(PIDLISTContxt *pidList_ctt,PIDContxt *pbr_ctt,void *stream_info_p);
ms_s64 
	mpegts_api_rateEmuLong(char * tag,char * exStr,RATEEMUContxt * sbrt,ms_s64 timeStream_cur,ms_bool flag_dbg);
ms_bool 
	mpegts_api_isMpeg(ms_string format,ms_u16 pid);
ms_string 
	mpegts_api_getStreamType(ms_u08 stream_type);
ms_string 
	mpegts_api_getServiceType(ms_u16 service_type);
ms_string 
	mpegts_api_getAVType(ms_u08 avType);
extern ms_void 
	mpegts_api_init(ms_void);
static ms_void 
	mpegts_init(ms_void ** param,ms_string tag,ms_u32 mode,void *stream_info, void *remapList_ctt);
static ms_s08 
	mpegts_parse(ms_void *param,ms_byte *buf, ms_s32 *len);
static ms_s32 
	mpegts_update(ms_void *param);
static ms_void 
	mpegts_deinit(ms_void **param);
#endif

#endif
